package com.iwhalecloud.bss.kite.cucc.service.attr.linkhandler;

import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.cucc.common.util.DateFormatUtils;
import com.iwhalecloud.bss.kite.cucc.service.attr.handler.SuddenTimeHandler;
import com.iwhalecloud.bss.kite.cucc.service.attr.handler.TempSuddenTimeAttrHandler;
import com.iwhalecloud.bss.kite.listener.handler.attr.annotation.AttrHandler;
import com.iwhalecloud.bss.kite.listener.handler.attr.impl.AbstractAttrLinkageHandler;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.inst.KiteAttr;
import com.iwhalecloud.bss.kite.manager.inst.KiteAttrValue;
import com.iwhalecloud.bss.kite.manager.inst.KiteInst;
import com.iwhalecloud.bss.kite.service.attr.AttrData;
import com.ztesoft.bss.common.exception.BssException;
import com.ztesoft.zsmart.core.log.ZSmartLogger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author wanghl386
 * @version 1.0
 * @date 2021/8/31 15:55
 * 计算临时带宽不能与突发带宽时间重叠
 */
@Service
@AttrHandler(TempSuddenTimeAttrHandler.class)
public class TempSuddenTimeAttrLinkHandler extends AbstractAttrLinkageHandler<AttrData> {
    private static final ZSmartLogger LOGGER = ZSmartLogger.getLogger(TempSuddenTimeAttrLinkHandler.class);

    @Autowired
    private IQuerySceneInstService querySceneInstService;

    @Override
    public void handle(KiteAttr kiteAttr, KiteInst kiteInst, AttrData attrData) {
        try {
            if ("2826".equals(attrData.getServiceOfferId())) {
                List<String> serviceOfferIdList = querySceneInstService.getExtParameterValue(attrData.getSceneInstId(), "BUSI_CHANGE_SERVICEOFFERID");
                if (KiteListUtils.isNotEmpty(serviceOfferIdList)&&serviceOfferIdList.contains("1091")) {

                    // 突发周期
                    String suddenCycle = kiteInst.getAttr("200001824").getValue();
                    // 突发开始时间
                    String suddenStart = kiteInst.getAttr("210004306").getValue();
                    // 突发开始时间desc
                    String suddenStartDesc = kiteInst.getAttr("210004306").getValueDesc();
                    // 突发结束时间
                    String suddenEnd = kiteInst.getAttr("210004307").getValue();
                    // 突发结束时间desc
                    String suddenEndDesc = kiteInst.getAttr("210004307").getValueDesc();
                    // 临时突发开始时间
                    String tempStart = kiteInst.getAttr("200001825").getValue();
                    // 临时突发结束时间
                    String tempEnd = kiteInst.getAttr("200001827").getValue();
                    if (KiteStringUtils.isNotEmpty(tempStart) && KiteStringUtils.isNotEmpty(tempEnd)
                    ) {
                        SimpleDateFormat sdf = new SimpleDateFormat(DateFormatUtils.DATE_MINUTE_FORMAT);//时间格式
                        Date startDate = sdf.parse(tempStart);
                        Date endDate = sdf.parse(tempEnd);
                        Calendar tempStartCal = Calendar.getInstance(); //获得一个日历
                        tempStartCal.setTime(startDate);
                        Calendar tempEndCal = Calendar.getInstance(); //获得一个日历
                        tempEndCal.setTime(endDate);
                        if (tempEndCal.before(tempStartCal)) {
                            BssException.throwOut("", "", "临时带宽的突发结束时间要大于突发开始时间");
                            return;
                        }
                        if (KiteStringUtils.isEmpty(suddenStart) || KiteStringUtils.isEmpty(suddenEnd) || KiteStringUtils.isEmpty(suddenCycle)) {
                            return;
                        }
                        // true 为不符合校验规则
                        boolean flag = false;
                        if ("100004331".equals(suddenCycle)) {
                            // 周
                            int days = getDaysBetween(tempEndCal, tempStartCal);
                            // 相差7天肯定不符合 周校验
                            if (days >= 7) {
                                flag = true;
                            } else {
                                int[] week1 = new int[14];
                                int[] week2 = new int[14];
                                int start = getWeekAndMonthCode("week",suddenStartDesc);
                                int end = getWeekAndMonthCode("week",suddenEndDesc);
                                for (int i = start - 1; i < end; i++) {
                                    week1[i] = 1;
                                    week1[i + 7] = 1;
                                }
                                // 14天，第二次循环标志位
                                boolean againFlag = false;
                                for (int i = 0; i <= days; i++) {
                                    int current = tempStartCal.get(Calendar.DAY_OF_WEEK) - 1;
                                    current = (current == 0 ? 7 : current);
                                    if (i != 0 && current == 1) {
                                        againFlag = true;
                                    }
                                    if (againFlag) {
                                        week2[current + 6] = 1;
                                    } else {
                                        week2[current - 1] = 1;
                                    }
                                    tempStartCal.add(Calendar.DATE, 1);
                                }
                                for (int i = 0; i < 14; i++) {
                                    if ((week1[i] & week2[i]) == 1) {
                                        flag = true;
                                        break;
                                    }
                                }
                            }

                        } else if ("100002333".equals(suddenCycle)) {
                            // 月
                            int days = getDaysBetween(tempEndCal, tempStartCal);
                            // 相差31天肯定不符合 月校验
                            if (days >= 31) {
                                flag = true;
                            }
                            int[] month1 = new int[62];
                            int[] month2 = new int[62];
                            int start = getWeekAndMonthCode("month",suddenStartDesc);
                            int end = getWeekAndMonthCode("month",suddenEndDesc);
                            for (int i = start - 1; i < end; i++) {
                                month1[i] = 1;
                                month1[i + 31] = 1;
                            }
                            // 62天，第二次循环标志位
                            boolean againFlag = false;
                            for (int i = 0; i <= days; i++) {
                                int current = tempStartCal.get(Calendar.DAY_OF_MONTH) - 1;
                                if (i != 0 && current == 0) {
                                    againFlag = true;
                                }
                                if (againFlag) {
                                    month2[current + 31] = 1;
                                } else {
                                    month2[current] = 1;
                                }
                                tempStartCal.add(Calendar.DATE, 1);
                            }
                            for (int i = 0; i < 62; i++) {
                                if ((month1[i] & month2[i]) == 1) {
                                    flag = true;
                                    break;
                                }
                            }

                        } else if ("100002481".equals(suddenCycle)) {
                            // 年
                            Calendar startCal = getYearCal(suddenStart);
                            Calendar endCal = getYearCal(suddenEnd);
                            flag = (!tempStartCal.before(startCal) && !tempStartCal.after(endCal)) || (!tempEndCal.before(startCal) && !tempEndCal.after(endCal));
                        }
                        if (flag) {
                            BssException.throwOut("", "", "临时带宽的突发开始时间至结束时间段不能与突发带宽的突发开始至突发结束时间段相重合");
                        }
                    }
                }
            }
        } catch (NumberFormatException | ParseException e) {
            LOGGER.error("handle-->", e, e.getMessage());
        }
    }

    @Override
    public void handleStyle(KiteAttr kiteAttr, KiteInst kiteInst, AttrData attrData) {

    }

    public static Integer getWeekAndMonthCode(String flag,String value){
        if(KiteStringUtils.equals(flag,"week")){
            switch (value){
                case "星期一":{
                    return 1;
                }
                case "星期二":{
                    return 2;
                }
                case "星期三":{
                    return 3;
                }
                case "星期四":{
                    return 4;
                }
                case "星期五":{
                    return 5;
                }
                case "星期六":{
                    return 6;
                }
                default :{
                    return 7;
                }
            }
        }else{
            value=value.substring(1,value.length()-1);
            return Integer.parseInt(value);
        }
    }

    private Calendar getYearCal(String date) throws ParseException {
        Calendar d = Calendar.getInstance();
        int year = d.get(Calendar.YEAR);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");//时间格式
        Date startSuddenDate = simpleDateFormat.parse(year+date);
        d.setTime(startSuddenDate);
        return d;
    }

    //计算相隔天数的方法
    private int getDaysBetween(Calendar d1, Calendar d2) {
        if (d1.after(d2)) {  // swap dates so that d1 is start and d2 is end
            java.util.Calendar swap = d1;
            d1 = d2;
            d2 = swap;
        }
        int days = d2.get(Calendar.DAY_OF_YEAR) - d1.get(Calendar.DAY_OF_YEAR);
        int y2 = d2.get(Calendar.YEAR);
        if (d1.get(Calendar.YEAR) != y2) {
            d1 = (Calendar) d1.clone();
            do {
                days += d1.getActualMaximum(Calendar.DAY_OF_YEAR);//得到当年的实际天数
                d1.add(Calendar.YEAR, 1);
            } while (d1.get(Calendar.YEAR) != y2);
        }
        return days;
    }
}
